#include <iostream>
#include <unistd.h>
#include <signal.h>

using namespace std;

// // 如果我们不想等待子进程，并且我们还想让子进程退出之后，自动释放僵尸子进程
// int main()
// {
//     // OS 默认就是忽略的
//     signal(SIGCHLD, SIG_IGN); // 手动设置对子进程进行忽略

//     if(fork() == 0)
//     {
//         cout << "child: " << getpid() << endl;
//         sleep(5);
//         exit(0);
//     }

//     while(true)
//     {
//         cout << "parent: " << getpid() << " 执行我自己的任务!" << endl;
//         sleep(1);
//     }
// }

void handler(int signum)
{
    cout << "子进程退出: " << signum << " father: " << getpid() << endl;
}

// 证明: 子进程退出，会想父进程发送信号
int main()
{
    signal(SIGCHLD, handler);
    if(fork() == 0)
    {
        cout << "child pid: " << getpid() << endl;
        sleep(100);
        exit(0);
    }

    while(true) sleep(1);
}

// volatile int flag = 0;

// void changeFlag(int signum)
// {
//     (void)signum;
//     cout <<"change flag: "<< flag;
//     flag = 1;
//     cout << "->" << flag << endl;
// }

// int main()
// {
//     signal(2, changeFlag);
//     while(!flag);
//     cout << "进程正常退出后：" << flag << endl;
// }


// void showPending(sigset_t *pending)
// {
//     for(int sig = 1; sig <= 31; sig++)
//     {
//         if(sigismember(pending, sig)) cout << "1";
//         else cout << "0";
//     }
//     cout << endl;
// }

// void handler(int signum)
// {
//     cout << "获取了一个信号: " << signum << endl;
//     cout << "获取了一个信号: " << signum << endl;
//     cout << "获取了一个信号: " << signum << endl;
//     cout << "获取了一个信号: " << signum << endl;
//     cout << "获取了一个信号: " << signum << endl;
//     cout << "获取了一个信号: " << signum << endl;

//     sigset_t pending;
//     int c=20;
//     while(true)
//     {
//         sigpending(&pending);
//         showPending(&pending);
//         c--;
//         if(!c) break;
//         sleep(1);
//     }
// }

// int main()
// {
//     //signal(2, SIG_IGN);
//     cout << "getpid: " << getpid() << endl;
//     // 内核数据类型，在用户栈定义
//     struct sigaction act, oact;
//     act.sa_flags=0;
//     sigemptyset(&act.sa_mask);
//     act.sa_handler=handler;

//     sigaddset(&act.sa_mask, 3);
//     sigaddset(&act.sa_mask, 4);
//     sigaddset(&act.sa_mask, 5);
//     sigaddset(&act.sa_mask, 6);
//     sigaddset(&act.sa_mask, 7);

//     //设置进当前调用进程的pcb中
//     sigaction(2, &act, &oact);

//     cout << "default action: " << (int)(oact.sa_handler) << endl;


//     while(true) sleep(1);
//     return 0;
// }